home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume90 / unix / cshel40a / part03 < prev    next >
Encoding:
Internet Message Format  |  1990-01-15  |  21.7 KB

  1. Path: xanth!cs.odu.edu!Amiga-Request
  2. From: Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v90i016: CShell 4.00A - alternative command interface, Part03/04
  5. Message-ID: <10989@xanth.cs.odu.edu>
  6. Date: 15 Jan 90 16:29:32 GMT
  7. Sender: tadguy@cs.odu.edu
  8. Reply-To: PERUGIA@ICNUCEVM.CNUCE.CNR.IT (Carlo & Cesare)
  9. Lines: 800
  10. Approved: tadguy@cs.odu.edu (Tad Guy)
  11.  
  12. Submitted-by: PERUGIA@ICNUCEVM.CNUCE.CNR.IT (Carlo & Cesare)
  13. Posting-number: Volume 90, Issue 016
  14. Archive-name: unix/cshell-4.00a/part03
  15.  
  16. #! /bin/sh
  17. # This is a shell archive.  Remove anything before this line, then unpack
  18. # it by saving it into a file and typing "sh file".  To overwrite existing
  19. # files, type "sh file -c".  You can also feed this as standard input via
  20. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  21. # will see the following message at the end:
  22. #        "End of archive 3 (of 4)."
  23. # Contents:  execom.c
  24. # Wrapped by tadguy@xanth on Mon Jan 15 11:28:11 1990
  25. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  26. if test -f 'execom.c' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'execom.c'\"
  28. else
  29. echo shar: Extracting \"'execom.c'\" \(19280 characters\)
  30. sed "s/^X//" >'execom.c' <<'END_OF_FILE'
  31. X/*
  32. X * EXECOM.C
  33. X *
  34. X * Matthew Dillon, 10 August 1986
  35. X *    Finally re-written.
  36. X *
  37. X * Version 2.07M by Steve Drew 10-Sep-87
  38. X *
  39. X * Version 4.00A by Carlo Borreo & Cesare Dieni 13-Jan-90
  40. X *
  41. X */
  42. X
  43. X#define F_EXACT 0
  44. X#define F_ABBR  1
  45. X
  46. X#define ST_COND   0x01
  47. X#define ST_NORED  0x02
  48. X#define ST_NOEXP  0x04
  49. X#define ST_AV     0x08 /* delimit args within a variable */
  50. X
  51. Xint has_wild = 0;                 /* set if any arg has wild card */
  52. X
  53. Xstruct COMMAND {
  54. X    int (*func)();
  55. X    short minargs;
  56. X    short stat;
  57. X    int val;
  58. X    char *name;
  59. X};
  60. X
  61. Xextern char *format_insert_string();
  62. Xextern char *mpush(), *exarg();
  63. X
  64. Xextern int do_basename(), do_tackon();
  65. Xextern int do_fltupper(), do_fltlower();
  66. Xextern int do_strleft(), do_strright(), do_strmid(), do_strlen();
  67. Xextern int do_fornum(), do_forline(), do_exec();
  68. Xextern int do_diskchange(), do_stack(), do_fault(), do_path(), do_pri();
  69. Xextern int do_rpn(), do_resident(), do_truerun(), do_aset(), do_howmany();
  70. Xextern int do_open(), do_close(), do_fileslist(), do_htype();
  71. Xextern int do_run(), do_number(), do_assign(), do_join();
  72. Xextern int do_quit(), do_set_var(), do_unset_var();
  73. Xextern int do_echo(), do_source(), do_mv(), do_addbuffers();
  74. Xextern int do_cd(), do_pwd(), do_rm(), do_mkdir(), do_history();
  75. Xextern int do_mem(), do_cat(), do_dir(), do_info(), do_inc();
  76. Xextern int do_foreach(), do_return(), do_if(), do_label(), do_goto();
  77. Xextern int do_input(), do_ver(), do_sleep(), do_help();
  78. Xextern int do_strhead(), do_strtail(), do_relabel();
  79. Xextern int do_copy(), do_date(), do_protect(), do_ps();
  80. Xextern int do_forever(), do_abortline(), do_strings(), do_touch();
  81. Xextern int do_window(), do_search(), do_filenote(), do_rxrec(), do_rxsend();
  82. Xchar *push_cpy();
  83. X
  84. Xstatic struct COMMAND Command[] = {
  85. Xdo_run,        0, ST_AV,    0,    "\001",   /* may call do_source */
  86. Xdo_abortline,    0, 0,        0,    "abortline",
  87. Xdo_addbuffers,    2, 0,        0,    "addbuffers",
  88. Xdo_set_var,    0, 0, LEVEL_ALIAS,    "alias",  /* uses avline */
  89. Xdo_aset,    1, 0,        0,    "aset",
  90. Xdo_assign,    0, 0,        0,    "assign",
  91. Xdo_basename,    2, 0,        0,    "basename",
  92. Xdo_cat,        0, 0,        0,    "cat",
  93. Xdo_cd,        0, 0,        0,    "cd",
  94. Xdo_close,    0, 0,        0,    "close",
  95. Xdo_copy,    1, 0,        0,    "copy",
  96. Xdo_copy,    1, 0,        0,    "cp",
  97. Xdo_date,    0, 0,        0,    "date",
  98. Xdo_inc,        1, 0,        -1,    "dec",
  99. Xdo_rm,        0, 0,        0,    "delete",
  100. Xdo_dir,        0, ST_NOEXP,    0,    "dir",
  101. Xdo_diskchange,    1, 0,        0,    "diskchange",
  102. Xdo_echo,    0, 0,        0,    "echo", /* uses avline */
  103. Xdo_if,        0, ST_COND,    1,    "else",
  104. Xdo_if,        0, ST_COND,    2,    "endif",
  105. Xdo_exec,    1, 0,        0,    "exec",
  106. Xdo_fault,    1, 0,        0,    "fault",
  107. Xdo_filenote,    2, 0,        0,    "filenote",
  108. Xdo_fileslist,    0, 0,        0,    "flist",
  109. Xdo_fltlower,    0, 0,        0,    "fltlower",
  110. Xdo_fltupper,    0, 0,        0,    "fltupper",
  111. Xdo_foreach,    3, ST_NORED,    0,    "foreach",
  112. Xdo_forever,    1, ST_NORED,    0,    "forever",
  113. Xdo_forline,    3, ST_NORED,    0,    "forline",
  114. Xdo_fornum,    4, ST_NORED,    0,    "fornum",
  115. Xdo_goto,    1, 0,        0,    "goto",
  116. Xdo_help,    0, 0,        0,    "help",
  117. Xdo_history,    0, 0,        0,    "history",
  118. Xdo_howmany,    0, 0,        0,    "howmany",
  119. Xdo_htype,    1, 0,        0,    "htype",
  120. Xdo_if,        1, ST_COND|ST_NORED,0,    "if",
  121. Xdo_inc,        1, 0,        1,    "inc",
  122. Xdo_info,    0, 0,        0,    "info",
  123. Xdo_input,    1, 0,        0,    "input",
  124. Xdo_join,    2, 0,        1,    "join",
  125. Xdo_label,    1, ST_COND,    0,    "label",
  126. Xdo_dir,        0, ST_NOEXP,    0,    "ls",
  127. Xdo_mkdir,    0, 0,        0,    "md",
  128. Xdo_mem,        0, 0,        0,    "mem",
  129. Xdo_mkdir,    0, 0,        0,    "mkdir",
  130. Xdo_mv,        2, 0,        0,    "mv",
  131. Xdo_open,    3, 0,        0,    "open",
  132. Xdo_path,    0, 0,        0,    "path",
  133. Xdo_pri,        2, 0,        0,    "pri",
  134. Xdo_protect,    2, 0,        0,    "protect",
  135. Xdo_ps,        0, 0,        0,    "ps",
  136. Xdo_pwd,        0, 0,        0,    "pwd",
  137. Xdo_quit,    0, ST_NORED,    0,    "quit",
  138. Xdo_truerun,    1, ST_NORED,    1,    "rback",
  139. Xdo_mv,        2, 0,        0,    "rename",
  140. Xdo_relabel,    2, 0,        0,    "relabel",
  141. Xdo_resident,    0, 0,        0,    "resident",
  142. Xdo_return,    0, 0,        0,    "return",
  143. Xdo_rm,        0, 0,        0,    "rm",
  144. Xdo_rpn,        0, ST_NOEXP|ST_NORED,0,    "rpn",
  145. Xdo_rxrec,    1, 0,        0,    "rxrec",
  146. Xdo_rxsend,    2, 0,        0,    "rxsend",
  147. Xdo_truerun,    1, ST_NORED,    0,    "run",
  148. Xdo_search,    2, 0,        0,    "search",
  149. Xdo_set_var,    0, ST_AV, LEVEL_SET,    "set",
  150. Xdo_sleep,    0, 0,        0,    "sleep",
  151. Xdo_source,    0, ST_NORED|ST_AV, 0,    "source", /* uses avline */
  152. Xdo_stack,    0, 0,        0,    "stack",
  153. Xdo_strhead,    3, 0,        0,    "strhead",
  154. Xdo_strings,    1, 0,        0,    "strings",
  155. Xdo_strleft,    3, 0,        0,    "strleft",
  156. Xdo_strlen,    2, 0,        0,    "strlen",
  157. Xdo_strmid,    3, 0,        0,    "strmid",
  158. Xdo_strright,    3, 0,        0,    "strright",
  159. Xdo_strtail,    3, 0,        0,    "strtail",
  160. Xdo_tackon,    3, 0,        0,    "tackon",
  161. Xdo_touch,    0, 0,        0,    "touch",
  162. Xdo_cat,        0, 0,        0,    "type",
  163. Xdo_unset_var,    0, 0, LEVEL_ALIAS,    "unalias",
  164. Xdo_unset_var,    0, 0, LEVEL_SET  ,    "unset",
  165. Xdo_ver,        0, 0,        0,    "version",
  166. Xdo_window,    0, ST_NOEXP,    0,    "window",
  167. X'\0',        0, 0,        0,    NULL
  168. X};
  169. X
  170. Xstatic unsigned char elast;        /* last end delimeter */
  171. Xstatic char Cin_ispipe, Cout_ispipe;
  172. X
  173. Xexec_command(base)
  174. Xchar *base;
  175. X{
  176. Xregister char *scr;
  177. Xchar buf[32];
  178. X
  179. Xif (!H_stack) {
  180. X    add_history(base);
  181. X    sprintf(buf, "%d", H_tail_base + H_len);
  182. X    set_var(LEVEL_SET, v_histnum, buf);
  183. X    }
  184. Xscr = malloc((strlen(base) << 2) + 2);
  185. Xpreformat(base, scr);
  186. Xreturn (fcomm(scr, 1) ? -1 : 1);
  187. X}
  188. X
  189. Xisalphanum(c)
  190. Xregister char c;
  191. X{
  192. Xreturn (
  193. X    (c >= '0' && c <= '9') ||
  194. X    (c >= 'a' && c <= 'z') ||
  195. X    (c >= 'A' && c <= 'Z') ||
  196. X    (c == '_')
  197. X    );
  198. X}
  199. X
  200. Xpreformat(s, d)
  201. Xregister char *s, *d;
  202. X{
  203. Xregister int si, di, qm;
  204. X
  205. Xsi = di = qm = 0;
  206. Xwhile (s[si] == ' ' || s[si] == 9) ++si;
  207. Xwhile (s[si]) {
  208. X    if (qm && s[si] != '\"' && s[si] != '\\') {
  209. X        d[di++] = s[si++] | 0x80;
  210. X        continue;
  211. X        }
  212. X    switch (s[si]) {
  213. X        case ' ':
  214. X        case 9:
  215. X            d[di++] = ' ';
  216. X            while (s[si] == ' ' || s[si] == 9) ++si;
  217. X            if (s[si] == 0 || s[si] == '|' || s[si] == ';') --di;
  218. X            break;
  219. X        case '*':
  220. X        case '?':
  221. X            d[di++] = 0x80;
  222. X        case '!':
  223. X            d[di++] = s[si++];
  224. X            break;
  225. X        case '#':
  226. X            d[di++] = '\0';
  227. X            while (s[si]) ++si;
  228. X            break;
  229. X        case ';':
  230. X        case '|':
  231. X            d[di++] = s[si++];
  232. X            while (s[si] == ' ' || s[si] == 9) ++si;
  233. X            break;
  234. X        case '\\':
  235. X            d[di++] = s[++si] | 0x80;
  236. X            if (s[si]) ++si;
  237. X            break;
  238. X        case '\"':
  239. X            qm = 1 - qm;
  240. X            ++si;
  241. X            break;
  242. X        case '^':
  243. X            d[di++] = s[++si] & 0x1F;
  244. X            if (s[si]) ++si;
  245. X            break;
  246. X        case '$': /* search end of var name and place false space */
  247. X            d[di++] = 0x80;
  248. X            d[di++] = s[si++];
  249. X            while (isalphanum(s[si])) d[di++] = s[si++];
  250. X            d[di++] = 0x80;
  251. X            break;
  252. X        default:
  253. X            d[di++] = s[si++];
  254. X            break;
  255. X        }
  256. X    }
  257. Xd[di++]=0;
  258. Xd[di]=0;
  259. Xif (debug) fprintf (stderr,"PREFORMAT: %d :%s:\n", strlen(d), d);
  260. X}
  261. X
  262. Xextern BPTR extOpen();
  263. X
  264. X/*
  265. X * process formatted string.  ' ' is the delimeter.
  266. X *
  267. X *    0: check '\0': no more, stop, done.
  268. X *    1: check $.     if so, extract, format, insert
  269. X *    2: check alias. if so, extract, format, insert. goto 1
  270. X *    3: check history or substitution, extract, format, insert. goto 1
  271. X *
  272. X *    4: assume first element now internal or disk based command.
  273. X *
  274. X *    5: extract each ' ' or 0x80 delimited argument and process, placing
  275. X *       in av[] list (except 0x80 args appended).  check in order:
  276. X *
  277. X *             '$'         insert string straight
  278. X *             '>'         setup stdout
  279. X *             '>>'        setup stdout flag for append
  280. X *             '<'         setup stdin
  281. X *             '*' or '?'  do directory search and insert as separate args.
  282. X *
  283. X *             ';' 0 '|'   end of command.  if '|' setup stdout
  284. X *                          -execute command, fix stdin and out (|) sets
  285. X *                           up stdin for next guy.
  286. X */
  287. X
  288. X
  289. Xfcomm(str, freeok)
  290. Xregister char *str;
  291. X{
  292. X   static int alias_count;
  293. X   int p_alias_count = 0;
  294. X   char *istr;
  295. X   char *nextstr;
  296. X   char *command;
  297. X   char *pend_alias = NULL;
  298. X   char err = 0;
  299. X   has_wild = 0;
  300. X
  301. X   ++alias_count;
  302. X
  303. X   mpush_base();
  304. X   if (*str == 0)
  305. X      goto done1;
  306. Xstep1:
  307. X   if (alias_count == MAXALIAS || ++p_alias_count == MAXALIAS) {
  308. X      fprintf(stderr,"Alias Loop\n");
  309. X      err = 20;
  310. X      goto done1;
  311. X   }
  312. X/*
  313. X   if (str[1] == '$') {
  314. X      if (istr = get_var (LEVEL_SET, str + 2))
  315. X         str = format_insert_string(str, istr, &freeok);
  316. X   }
  317. X*/
  318. X   istr = NULL;
  319. X   if (*(unsigned char *)str < 0x80)
  320. X      istr = get_var (LEVEL_ALIAS, str);  /* only if not \command */
  321. X   *str &= 0x7F;                          /* remove \ teltail     */
  322. X   if (istr) {
  323. X      if (*istr == '%') {
  324. X         pend_alias = istr;
  325. X      } else {
  326. X         str = format_insert_string(str, istr, &freeok);
  327. X         goto step1;
  328. X      }
  329. X   }
  330. X   if (*str == '!') {
  331. X      char *p, c;                     /* fix to allow !cmd1;!cmd2 */
  332. X      for(p = str; *p && *p != ';' ; ++p);
  333. X      c = *p;
  334. X      *p = '\0';
  335. X      istr = get_history(str);
  336. X      *p = c;
  337. X      replace_head(istr);
  338. X      str = format_insert_string(str, istr, &freeok);
  339. X      goto step1;
  340. X   }
  341. X   nextstr = str;
  342. X   command = exarg(&nextstr);
  343. X   if (*command == 0)
  344. X      goto done0;
  345. X   if (pend_alias == 0) {
  346. X      if (cmd_stat(command) & ST_COND)
  347. X         goto skipgood;
  348. X   }
  349. X   if (disable || forward_goto) {
  350. X      while (elast && elast != ';' && elast != '|')
  351. X         exarg(&nextstr);
  352. X      goto done0;
  353. X   }
  354. Xskipgood:
  355. X   {
  356. X      register char *arg, *ptr, *scr;
  357. X      short redir;
  358. X      short doexpand;
  359. X      short cont;
  360. X      short inc;
  361. X
  362. X      ac = 1;
  363. X      av[0] = command;
  364. Xstep5:                                          /* ac = nextac */
  365. X      if (!elast || elast == ';' || elast == '|')
  366. X         goto stepdone;
  367. X
  368. X      av[ac] = '\0';
  369. X      cont = 1;
  370. X      doexpand = redir = inc = 0;
  371. X
  372. X      while (cont && elast) {
  373. X         int cstat = cmd_stat(command);
  374. X
  375. X         ptr = exarg(&nextstr);
  376. X         inc = 1;
  377. X         arg = "";
  378. X         cont = (elast == 0x80);
  379. X         switch (*ptr) {
  380. X         case '<':
  381. X            redir = -2;
  382. X         case '>':
  383. X            if (cstat & (ST_NORED | ST_COND)) {
  384. X                                                        /* don't extract   */
  385. X                redir = 0;                              /* <> stuff if its */
  386. X                arg = ptr;                              /* external cmd.   */
  387. X                break;
  388. X            }
  389. X            ++redir;
  390. X            arg = ptr + 1;
  391. X            if (*arg == '>') {
  392. X               redir = 2;        /* append >> */
  393. X               ++arg;
  394. X            }
  395. X            cont = 1;
  396. X            break;
  397. X         case '$':
  398. X            /* restore args if from set command or pend_alias */
  399. X            if ((arg = get_var(LEVEL_SET, ptr + 1)) != NULL) {
  400. X               if (cstat & ST_COND) {
  401. X                  char *tp;
  402. X                  tp = push_cpy(arg);
  403. X                  arg = tp;
  404. X               }
  405. X               else {
  406. X                  char *pe, sv;
  407. X                  while (pe = index(arg,0xA0)) {
  408. X                     sv = *pe;
  409. X                     *pe = '\0';
  410. X                     av[ac++] = push_cpy(arg);
  411. X                     *pe = sv;
  412. X                     av[ac] = '\0';
  413. X                     arg = pe+1;
  414. X                  }
  415. X               }
  416. X            }
  417. X            else
  418. X               arg = ptr;
  419. X            break;
  420. X         case '*':
  421. X         case '?':
  422. X            if ((cstat & ST_NOEXP) == 0)
  423. X               doexpand = 1;
  424. X            arg = ptr;
  425. X            break;
  426. X         default:
  427. X            arg = ptr;
  428. X            break;
  429. X         }
  430. X
  431. X         /* Append arg to av[ac] */
  432. X
  433. X         for (scr = arg; *scr; ++scr)
  434. X            *scr &= 0x7F;
  435. X         if (av[ac]) {
  436. X            register char *old = av[ac];
  437. X            av[ac] = mpush(strlen(arg)+strlen(av[ac]));
  438. X            strcpy(av[ac], old);
  439. X            strcat(av[ac], arg);
  440. X         } else {
  441. X            av[ac] = push_cpy(arg);
  442. X         }
  443. X         if (elast != 0x80)
  444. X            break;
  445. X      }
  446. X
  447. X      /* process expansion */
  448. X
  449. X      if (doexpand) {
  450. X         char **eav, **ebase;
  451. X         int eac;
  452. X         has_wild = 1;
  453. X         eav = ebase = expand(av[ac], &eac);
  454. X         inc = 0;
  455. X         if (eav) {
  456. X            if (ac + eac + 2 > MAXAV) {
  457. X               ierror (NULL, 506);
  458. X               err = 1;
  459. X            } else {
  460. X               QuickSort(eav, eac);
  461. X               for (; eac; --eac, ++eav)
  462. X                  av[ac++] = push_cpy(*eav);
  463. X            }
  464. X            free_expand (ebase);
  465. X         }
  466. X      }
  467. X
  468. X      /* process redirection  */
  469. X
  470. X      if (redir && !err) {
  471. X         register char *file = (doexpand) ? av[--ac] : av[ac];
  472. X
  473. X         if (redir < 0)
  474. X            Cin_name = file;
  475. X         else {
  476. X            Cout_name = file;
  477. X            Cout_append = (redir == 2);
  478. X         }
  479. X         inc = 0;
  480. X      }
  481. X
  482. X      /* check elast for space */
  483. X
  484. X      if (inc) {
  485. X         ++ac;
  486. X         if (ac + 2 > MAXAV) {
  487. X            ierror (NULL, 506);
  488. X            err = 1;                /* error condition */
  489. X            elast = 0;              /* don't process any more arguemnts */
  490. X         }
  491. X      }
  492. X      if (elast == ' ')
  493. X         goto step5;
  494. X   }
  495. Xstepdone:
  496. X   av[ac] = '\0';
  497. X
  498. X   /* process pipes via files */
  499. X
  500. X   if (elast == '|' && !err) {
  501. X      static int which;             /* 0 or 1 in case of multiple pipes */
  502. X      which = 1 - which;
  503. X      Cout_name = (which) ? Pipe1 : Pipe2;
  504. X      Cout_ispipe = 1;
  505. X   }
  506. X
  507. X
  508. X   if (err)
  509. X      goto done0;
  510. X
  511. X   {
  512. X      register int i;
  513. X      char save_elast;
  514. X      char *compile_av();
  515. X      register char *avline;
  516. X      unsigned char delim = ' ';
  517. X
  518. X      save_elast = elast;
  519. X      if (pend_alias || (cmd_stat(command) & ST_AV))
  520. X         delim = 0xA0;
  521. X      avline = compile_av(av,((pend_alias) ? 1 : 0), ac, delim, 0);
  522. X
  523. X      if (pend_alias) {                               /* special % alias */
  524. X         register char *ptr, *scr;
  525. X         for (ptr = pend_alias; *ptr && *ptr != ' '; ++ptr);
  526. X         set_var (LEVEL_SET, pend_alias + 1, avline);
  527. X         free (avline);
  528. X
  529. X         scr = malloc((strlen(ptr) << 2) + 2);
  530. X         preformat (ptr, scr);
  531. X         fcomm (scr, 1);
  532. X         unset_var (LEVEL_SET, pend_alias + 1);
  533. X      } else {                                        /* normal command  */
  534. X         register int ccno;
  535. X         long  oldcin  = Myprocess->pr_CIS;
  536. X         long  oldcout = Myprocess->pr_COS;
  537. X         char *Cin_buf;
  538. X         struct FileHandle *ci;
  539. X         long oldbuf;
  540. X
  541. X         fflush(stdout);
  542. X         ccno = find_command (command);
  543. X         if ((Command[ccno].stat & (ST_NORED | ST_COND)) == 0) {
  544. X            if (Cin_name) {
  545. X               if ((Cin = (long)extOpen(Cin_name,1005L)) == 0L) {
  546. X                  ierror (NULL, 504);
  547. X                  err = 1;
  548. X                  Cin_name = '\0';
  549. X               } else {
  550. X                  Myprocess->pr_CIS = _devtab[stdin->_unit].fd = Cin;
  551. X                  ci = (struct FileHandle *)(((long)Cin)<<2);
  552. X                  Cin_buf = (char *)AllocMem(202L, MEMF_PUBLIC);
  553. X                  oldbuf = ci->fh_Buf;
  554. X                  if (ci->fh_Buf == 0) /* fexec expects a CIS buffer */
  555. X                     ci->fh_Buf = (long)Cin_buf>>2;
  556. X               }
  557. X            }
  558. X            if (Cout_name) {
  559. X               if (Cout_append && (Cout =(long)extOpen(Cout_name, 1005L)) ) {
  560. X                     Seek(Cout, 0L, 1L);
  561. X               } else {
  562. X                  Cout = (long)extOpen(Cout_name,1006L);
  563. X               }
  564. X               if (Cout == NULL) {
  565. X                  err = 1;
  566. X                  ierror (NULL, 504);
  567. X                  Cout_name = '\0';
  568. X                  Cout_append = 0;
  569. X               } else {
  570. X                  Myprocess->pr_COS = _devtab[stdout->_unit].fd = Cout;
  571. X               }
  572. X            }
  573. X         }
  574. X         if (ac < Command[ccno].minargs + 1) {
  575. X            ierror (NULL, 500);
  576. X            err = -1;
  577. X         } else if (!err) {
  578. X            i = (*Command[ccno].func)(avline, Command[ccno].val);
  579. X            if (i < 0)
  580. X               i = 20;
  581. X            err = i;
  582. X         }
  583. X         free (avline);
  584. X         if (E_stack == 0 && Lastresult != err) {
  585. X            Lastresult = err;
  586. X            seterr();
  587. X         }
  588. X         if ((Command[ccno].stat & (ST_NORED | ST_COND)) == 0) {
  589. X            if (Cin_name) {
  590. X               fflush(stdin);
  591. X               clearerr(stdin);
  592. X               ci->fh_Buf = oldbuf;
  593. X               extClose(Cin);
  594. X               FreeMem(Cin_buf, 202L);
  595. X            }
  596. X            if (Cout_name) {
  597. X               fflush(stdout);
  598. X               clearerr(stdout);
  599. X               stdout->_flags &= ~_DIRTY;    /* because of nil: device */
  600. X               extClose(Cout);
  601. X               Cout_append = 0;
  602. X            }
  603. X         }
  604. X         Myprocess->pr_CIS =  _devtab[stdin->_unit].fd  = oldcin;
  605. X         Myprocess->pr_COS =  _devtab[stdout->_unit].fd = oldcout;
  606. X      }
  607. X
  608. X      if (Cin_ispipe && Cin_name)
  609. X         DeleteFile(Cin_name);
  610. X      if (Cout_ispipe) {
  611. X         Cin_name = Cout_name;         /* ok to assign.. static name */
  612. X         Cin_ispipe = 1;
  613. X      } else {
  614. X         Cin_name = '\0';
  615. X      }
  616. X      Cout_name = '\0';
  617. X      Cout_ispipe = 0;
  618. X      elast = save_elast;
  619. X   }
  620. X   mpop_tobase();                      /* free arguments   */
  621. X   mpush_base();                       /* push dummy base  */
  622. X
  623. Xdone0:
  624. X   {
  625. X      char *str;
  626. X      if (err && E_stack == 0) {
  627. X         str = get_var(LEVEL_SET, v_except);
  628. X         if (err >= ((str)?atoi(str):1)) {
  629. X            if (str) {
  630. X               ++H_stack;
  631. X               ++E_stack;
  632. X               exec_command(str);
  633. X               --E_stack;
  634. X               --H_stack;
  635. X            } else {
  636. X               Exec_abortline = 1;
  637. X            }
  638. X         }
  639. X      }
  640. X      if (elast != 0 && Exec_abortline == 0)
  641. X         err = fcomm(nextstr, 0);
  642. X      Exec_abortline = 0;
  643. X      if (Cin_name)
  644. X         DeleteFile(Cin_name);
  645. X      Cin_name = NULL;
  646. X      Cin_ispipe = 0;
  647. X   }
  648. Xdone1:
  649. X   mpop_tobase();
  650. X   if (freeok)
  651. X      free(str);
  652. X   --alias_count;
  653. X   return ((int)err);                  /* TRUE = error occured    */
  654. X}
  655. X
  656. X
  657. Xchar *
  658. Xexarg(ptr)
  659. Xunsigned char **ptr;
  660. X{
  661. X   register unsigned char *end;
  662. X   register unsigned char *start;
  663. X
  664. X   start = end = *ptr;
  665. X   while (*end && *end != 0x80 && *end != ';' && *end != '|' && *end != ' ')
  666. X      ++end;
  667. X   elast = *end;
  668. X   *end = '\0';
  669. X   *ptr = end + 1;
  670. X   return ((char *)start);
  671. X}
  672. X
  673. Xstatic char **Mlist;
  674. X
  675. Xmpush_base()
  676. X{
  677. X   char *str;
  678. X
  679. X   str = malloc(5);
  680. X   *(char ***)str = Mlist;
  681. X   str[4] = 0;
  682. X   Mlist = (char **)str;
  683. X}
  684. X
  685. Xchar *
  686. Xmpush(bytes)
  687. X{
  688. X   char *str;
  689. X
  690. X   str = malloc(6 + bytes + 2);   /* may need extra 2 bytes in do_run() */
  691. X   *(char ***)str = Mlist;
  692. X   str[4] = 1;
  693. X   Mlist = (char **)str;
  694. X   return (str + 5);
  695. X}
  696. X
  697. Xmpop_tobase()
  698. X{
  699. X   register char *next;
  700. X   while (Mlist) {
  701. X      next = *Mlist;
  702. X      if (((char *)Mlist)[4] == 0) {
  703. X         free (Mlist);
  704. X         Mlist = (char **)next;
  705. X         break;
  706. X      }
  707. X      free (Mlist);
  708. X      Mlist = (char **)next;
  709. X   }
  710. X}
  711. X
  712. X
  713. X/*
  714. X * Insert 'from' string in front of 'str' while deleting the
  715. X * first entry in 'str'.  if freeok is set, then 'str' will be
  716. X * free'd
  717. X */
  718. X
  719. Xchar *format_insert_string(str, from, freeok)
  720. Xchar *str;
  721. Xchar *from;
  722. Xint *freeok;
  723. X{
  724. Xregister char *new1, *new2;
  725. Xregister unsigned char *strskip;
  726. Xint len;
  727. X
  728. Xfor (strskip = (unsigned char *)str;
  729. X        *strskip && *strskip != ' ' 
  730. X        && *strskip != ';' && *strskip != '|'
  731. X        && *strskip != 0x80; ++strskip);
  732. Xlen = strlen(from);
  733. Xnew1 = malloc((len << 2) + 2);
  734. Xpreformat(from, new1);
  735. Xlen = strlen(new1) + strlen(strskip);
  736. Xnew2 = malloc(len+2);
  737. Xstrcpy(new2, new1);
  738. Xstrcat(new2, strskip);
  739. Xnew2[len+1] = 0;
  740. Xfree (new1);
  741. Xif (*freeok) free (str);
  742. X*freeok = 1;
  743. Xreturn new2;
  744. X}
  745. X
  746. Xcmd_stat(str)
  747. Xchar *str;
  748. X{
  749. Xreturn(Command[find_command(str)].stat);
  750. X}
  751. X
  752. Xfind_command(str)
  753. Xchar *str;
  754. X{
  755. Xregister unsigned short i;
  756. Xint len = strlen(str);
  757. X
  758. Xfor (i = 0; Command[i].func; ++i)
  759. X    if ( ! strncmp(str, Command[i].name, len)) return (int)i;
  760. Xreturn 0;
  761. X}
  762. X
  763. Xdo_help()
  764. X{
  765. Xregister struct COMMAND *com;
  766. Xint i=0;
  767. X
  768. Xfor (com = &Command[1]; com->func; ++com) {
  769. X    printf ("%-12s", com->name);
  770. X    if (++i % 6 == 0) printf("\n");
  771. X    }
  772. Xprintf("\n");
  773. Xreturn 0;
  774. X}
  775. X
  776. Xchar *push_cpy(s)
  777. Xchar *s;
  778. X{
  779. Xreturn strcpy(mpush(strlen(s)), s);
  780. X}
  781. END_OF_FILE
  782. if test 19280 -ne `wc -c <'execom.c'`; then
  783.     echo shar: \"'execom.c'\" unpacked with wrong size!
  784. fi
  785. # end of 'execom.c'
  786. fi
  787. echo shar: End of archive 3 \(of 4\).
  788. cp /dev/null ark3isdone
  789. MISSING=""
  790. for I in 1 2 3 4 ; do
  791.     if test ! -f ark${I}isdone ; then
  792.     MISSING="${MISSING} ${I}"
  793.     fi
  794. done
  795. if test "${MISSING}" = "" ; then
  796.     echo You have unpacked all 4 archives.
  797.     rm -f ark[1-9]isdone
  798. else
  799.     echo You still need to unpack the following archives:
  800.     echo "        " ${MISSING}
  801. fi
  802. ##  End of shell archive.
  803. exit 0
  804. -- 
  805. Submissions to comp.sources.amiga and comp.binaries.amiga should be sent to:
  806.     amiga@cs.odu.edu    
  807. or    amiga@xanth.cs.odu.edu    ( obsolescent mailers may need this address )
  808. or    ...!uunet!xanth!amiga    ( very obsolescent mailers need this address )
  809.  
  810. Comments, questions, and suggestions s should be addressed to ``amiga-request''
  811. (only use ``amiga'' for submissions) at the above addresses.
  812.